package com.skirmisher.video.service.impl;

import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vs.model.v20181212.*;
import com.skirmisher.video.aliVideo.device.AliDevice;
import com.skirmisher.video.aliVideo.group.AliGroup;
import com.skirmisher.video.aliVideo.record.AliRecord;
import com.skirmisher.video.aliVideo.stream.AliStream;
import com.skirmisher.video.entity.frame.AliPropertiesEntity;
import com.skirmisher.video.entity.video.*;
import com.skirmisher.video.mapper.AliVideoMapper;
import com.skirmisher.video.service.AliVideoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @ClassName AliVideoServiceImpl
 * @Description TODO
 * @Author hanwangxin
 * @Date 2020/11/8 7:09 下午
 * @Version 1.0
 */
@Service
@Transactional
public class AliVideoServiceImpl implements AliVideoService {

    @Autowired
    private AliDevice aliDevice;

    @Autowired
    private AliGroup aliGroup;

    @Autowired
    private AliStream aliStream;

    @Autowired
    private AliRecord aliRecord;

    @Autowired
    private AliPropertiesEntity aliPropertiesEntity;

    @Resource
    private AliVideoMapper aliVideoMapper;

    @Override
    public void startDevice(String deviceId) throws ClientException {

        aliDevice.startDevice(deviceId);
    }

    @Override
    public void stopDevice(String deviceId) throws ClientException {

        aliDevice.stopDevice(deviceId);
    }

    @Override
    public void download() throws ClientException {

        List<GroupEntity> groupList = new ArrayList<>();
        List<DeviceEntity> deviceList = new ArrayList<>();
        List<StreamEntity> streamList = new ArrayList<>();

        //获取空间信息
        List<DescribeGroupsResponse.Group> groups = aliGroup.describeGroups();
        for (DescribeGroupsResponse.Group group : groups) {
            GroupEntity groupEntity = new GroupEntity();
            String id = group.getId();
            groupEntity.setId(id);
            groupEntity.setName(group.getName());
            groupList.add(groupEntity);

            //获取空间下的设备信息
            List<DescribeDevicesResponse.Device> devices = aliDevice.describeDevices(id);
            for (DescribeDevicesResponse.Device device : devices) {
                DeviceEntity deviceEntity = new DeviceEntity();
                String deviceId = device.getId();

                deviceEntity.setId(deviceId);
                deviceEntity.setName(device.getName());
                deviceEntity.setStatus(device.getStatus());
                deviceEntity.setGroup_id(id);
                deviceList.add(deviceEntity);

                //获取空间下面流的信息
                List<DescribeStreamsResponse.Stream> streams = aliStream.describeStreams(deviceId);
                for (DescribeStreamsResponse.Stream stream : streams) {
                    String streamId = stream.getId();
                    StreamEntity streamEntity = new StreamEntity();
                    streamEntity.setId(streamId);
                    streamEntity.setName(stream.getName());
                    streamEntity.setDevice_id(deviceId);
                    streamEntity.setGroup_id(id);
                    streamEntity.setStream_url(aliStream.describeStreamURL(streamId,aliPropertiesEntity.getOutProtocol(),aliPropertiesEntity.getAuthKey()).getUrl());
                    streamEntity.setUrl_creatTime(fromtTime(0));
                    streamEntity.setUrl_endTime(fromtTime(aliPropertiesEntity.getActivitiTime()));
                    streamEntity.setStatus(stream.getStatus());

                    streamList.add(streamEntity);
                }
            }


        }

        aliVideoMapper.deletGroup();
        aliVideoMapper.deletDevice();
        aliVideoMapper.deletStream();

        aliVideoMapper.saveGroup(groupList);
        aliVideoMapper.saveDevice(deviceList);
        aliVideoMapper.saveStream(streamList);

    }

    @Override
    public String getDeviceUrl(String deviceId) throws ClientException {

        String now = fromtTime(0);
        StreamEntity stream = new StreamEntity();
        stream.setDevice_id(deviceId);
        stream.setUrl_endTime(now);

        StreamEntity deviceUrl = aliVideoMapper.getDeviceUrl(stream);
        if (deviceUrl == null){
                List<DescribeStreamsResponse.Stream> streams = aliStream.describeStreams(deviceId);
                DescribeStreamURLResponse describeStreamURLResponse = aliStream.describeStreamURL(streams.get(0).getId(), aliPropertiesEntity.getOutProtocol(),
                        aliPropertiesEntity.getAuthKey());
                //将获取到的最新url放置到表中
                String newUrl = describeStreamURLResponse.getUrl();
                stream.setUrl_endTime(fromtTime(aliPropertiesEntity.getActivitiTime()));
                stream.setStream_url(newUrl);
                stream.setUrl_creatTime(now);

                StreamEntity streamEntity = aliVideoMapper.getStream(deviceId);
                if (streamEntity == null){

                    //获取设备信息
                    DescribeStreamsResponse.Stream stream1 = streams.get(0);
                    stream.setId(UUID.randomUUID().toString());
                    stream.setName(stream1.getName());
                    stream.setGroup_id(stream1.getGroupId());
                    stream.setStatus(stream1.getStatus());
                    List<StreamEntity> listStream = new ArrayList<>();
                    listStream.add(stream);
                    aliVideoMapper.saveStream(listStream);


                }else {
                    aliVideoMapper.updateStream(stream);
                }

                return newUrl;
            }else{
                return deviceUrl.getStream_url();
            }
        }



    @Override
    public void getDevice(DevicePageQueryEntity pageQuery) {

        List<DeviceEntity> list =aliVideoMapper.getDeviceList(pageQuery);

        int count = aliVideoMapper.getDeviceCount(pageQuery);
        pageQuery.setCount(count);
        pageQuery.setDevicelist(list);

    }

    @Override
    public String snapshot(String deviceId) throws ClientException {
        //根据设备id获取流信息
        StreamEntity stream = aliVideoMapper.getStream(deviceId);

        //调用阿里截图
        CreateStreamSnapshotResponse streamSnapshot = aliRecord.createStreamSnapshot(stream.getId());

        //保存录像
        RecordEntity record = new RecordEntity();
        record.setId(UUID.randomUUID().toString());
        record.setCreat_time(fromtTime(0));
        record.setDevice_id(stream.getDevice_id());
        record.setGroup_id(stream.getGroup_id());
        record.setStream_id(stream.getId());
        record.setType("image");
        record.setUrl(streamSnapshot.getUrl());

        aliVideoMapper.saveRecord(record);


        return streamSnapshot.getUrl();
    }

    @Override
    public void recordCallBack(RecordCallBackEntity callBack) {

        //判断是否获取到url
        String uri = callBack.getUri();
        if (!StringUtils.isEmpty(uri)){
            //获取流信息
            StreamEntity stream = aliVideoMapper.getStream4Name(callBack.getStream());
            //保存录像
            RecordEntity record = new RecordEntity();
            record.setId(UUID.randomUUID().toString());
            record.setCreat_time(fromtTime(0));
            record.setDevice_id(stream.getDevice_id());
            record.setGroup_id(stream.getGroup_id());
            record.setStream_id(stream.getId());
            record.setDuration(callBack.getDuration());
            record.setStart_time(formatTime(callBack.getStart_time()));
            record.setStop_time(formatTime(callBack.getStop_time()));
            record.setType("video");
            record.setUrl(aliPropertiesEntity.getOssAddress()+uri);

            aliVideoMapper.saveRecord(record);
        }else {
            System.out.println("阿里回调失败");
        }
    }

    @Override
    public String startRecordStream(String deviceId) throws ClientException {
        StreamEntity stream = aliVideoMapper.getStream(deviceId);

        aliRecord.startRecordStream(stream.getId());
        return null;
    }

    @Override
    public String stopRecordStream(String deviceId) throws ClientException {

        StreamEntity stream = aliVideoMapper.getStream(deviceId);

        aliRecord.stopRecordStream(stream.getId());
        return null;
    }

    @Override
    public void getRecord(RecordPageQueryEntity page) {

        List<RecordEntity> list =aliVideoMapper.getRecordList(page);

        int count = aliVideoMapper.getRecordCount(page);
        page.setCount(count);
        page.setRecordList(list);
    }

    @Override
    public void device2Project(Device2ProjectEntity device2Project) {

        device2Project.setId(UUID.randomUUID().toString());

        int flag = aliVideoMapper.getDevice4Project(device2Project);
        if (flag <= 0){
            //新增
            aliVideoMapper.device2Project(device2Project);
        }else{
            aliVideoMapper.updateDevice2Project(device2Project);
        }


    }

    @Override
    public void saveVideo2Project(Video2ProjectEntity video2Project) {
        //获取录像详情
        RecordEntity recordEntity = aliVideoMapper.getVideoById(video2Project.getVideId());

        ProjectVideoEntity proVideo = new ProjectVideoEntity();
        proVideo.setId(UUID.randomUUID().toString());
        proVideo.setCreate_time(recordEntity.getStart_time());
        proVideo.setCreator("admin");

        String device_name = recordEntity.getDevice_name();
        String url = recordEntity.getUrl();
        String[] split = url.split("/");
        String videoName = device_name +"-"+split[split.length-1];

        proVideo.setName(videoName);
        proVideo.setPath(url);
        proVideo.setProject_id(recordEntity.getProject_id());
        proVideo.setProject_name(recordEntity.getProject_name());
        proVideo.setTimes(recordEntity.getDuration().intValue());

        aliVideoMapper.saveProjectVideo(proVideo);
    }

    @Override
    public void creatDevice(NationalDeviceEntity device) throws ClientException {

        //调用设备新增接口
        String deviceId = aliDevice.createDevice(device);
        //String deviceId = "22222222225555";

        //新增设备
        DeviceEntity deviceEntity = new DeviceEntity();
        BeanUtils.copyProperties(device, deviceEntity);
        deviceEntity.setId(deviceId);
        deviceEntity.setName(device.getDeviceName());
        deviceEntity.setGroup_id(device.getGroupId());
        deviceEntity.setStatus("off");
        List<DeviceEntity> deviceList = new ArrayList<>();
        deviceList.add(deviceEntity);
        aliVideoMapper.saveDevice(deviceList);
        //新增绑定关系
        if (!StringUtils.isEmpty(device.getProjectId())){

            Device2ProjectEntity device2Project = new Device2ProjectEntity();
            device2Project.setId(UUID.randomUUID().toString());
            device2Project.setDeviceId(deviceId);
            device2Project.setDeviceName(device.getDeviceName());
            device2Project.setProjectCode(device.getProjectCode());
            device2Project.setProjectId(device.getProjectId());
            device2Project.setProjectName(device.getProjectName());

            aliVideoMapper.device2Project(device2Project);
        }

    }

    public String fromtTime(int addTime){
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime newTime = now.plusMinutes(addTime);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format = newTime.format(formatter);
        return  format;
    }

    private String formatTime(long time){

        Assert.notNull(time, "time is null");
        DateTimeFormatter ftf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()));
    }
}
